#include "SpaceFortress.h"

#include "Stringhash.h"
#include "CString.h"

Stringhash::Stringhash()
{
	text = "";
	hash = 0;
}

/*
	This may need to change char to TCHAR
*/
Stringhash::Stringhash(FString setText)
{
	// These are adjustable variables.
	// Could be static class members.
	int32 len = setText.Len();
	uint32 seed = 123;

	// 'm' and 'r' are mixing constants generated offline.
	// They're not really 'magic', they just happen to work well.
	const uint32 m = 0x5bd1e995;
	const int32 r = 24;

	// Initialize the hash to a 'random' value
	hash = seed ^ len;

	// Mix 4 bytes at a time into the hash
	const unsigned char * data = (const unsigned char *)*setText;
	while (len >= 4)
	{
		uint32 k = *(uint32 *)data;

		k *= m;
		k ^= k >> r;
		k *= m;

		hash *= m;
		hash ^= k;

		data += 4;
		len -= 4;
	}

	// Handle the last few bytes of the input array
	switch (len)
	{
	case 3: hash ^= data[2] << 16;
	case 2: hash ^= data[1] << 8;
	case 1: hash ^= data[0];
		hash *= m;
	};

	// Do a few final mixes of the hash to ensure the last few
	// bytes are well-incorporated.
	hash ^= hash >> 13;
	hash *= m;
	hash ^= hash >> 15;
}

Stringhash::Stringhash(const Stringhash& sh)
{
	text = sh.text;
	hash = sh.hash;
}

Stringhash Stringhash::operator=(const Stringhash& sh)
{
	return Stringhash(sh);
}

bool Stringhash::operator==(const Stringhash& sh)
{
	return hash == sh.hash;
}

bool Stringhash::operator!=(const Stringhash& sh)
{
	return hash != sh.hash;
}

bool Stringhash::operator<(const Stringhash& sh)
{
	return hash < sh.hash;
}

bool Stringhash::operator>(const Stringhash& sh)
{
	return hash > sh.hash;
}